#include "os.h"

extern void trap_vector(void);

void trap_init()
{
	/*
	 * 为机器模式设置陷阱向量（trap vector）的基地址
	 */
	w_mtvec((reg_t)trap_vector);
}

reg_t trap_handler(reg_t epc, reg_t cause)
{
	reg_t return_pc = epc;
	reg_t cause_code = cause & MCAUSE_MASK_ECODE;
	
	if (cause & MCAUSE_MASK_INTERRUPT) 
	{
		/* 异步陷阱--中断 */
		switch (cause_code) 
		{
		case 3:
			uart_puts("software interruption!\n");
			break;
		case 7:
			uart_puts("timer interruption!\n");
			break;
		case 11:
			uart_puts("external interruption!\n");
			break;
		default:
			printf("Unknown async exception! Code = %ld\n", cause_code);
			break;
		}
	} 
	else 
	{
		/* 同步陷阱--异常 */
		printf("Sync exceptions! Code = %ld\n", cause_code);
		//panic("OOPS! What can I do!");		//panic函数中是死循环，意味着无法从异常处理程序返回到主程序trap_test()
		return_pc += 4;		//返回到主程序trap_test()引发异常的下一条指令uart_puts()处继续执行
	}

	return return_pc;
}

void trap_test()
{
	/*
	 * 同步异常代码 = 7
	 * 存储/原子（AMO）访问错误
	 */
	*(int *)0x00000000 = 100;

	/*
	 * 同步异常代码 = 5
	 * 加载访问错误
	 */
	//int a = *(int *)0x00000000;

	uart_puts("Yeah! I'm return back from trap!\n");
}

